home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
PVDRIVER
/
MACFONTX.ZIP
/
XBIN23.ZIP
/
XBIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-13
|
19KB
|
900 lines
#ifndef lint
static char version[] = "xbin.c Version 2.3 09/30/85";
#endif lint
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef MSDOS
#include <sys/dir.h>
#endif
#ifndef MSDOS
#ifdef MAXNAMLEN /* 4.2 BSD */
#define FNAMELEN MAXNAMLEN
#else
#define FNAMELEN DIRSIZ
#endif
#else
#define FNAMELEN 8
#endif
#ifdef BSD
#include <sys/time.h>
#include <sys/timeb.h>
#define search_last rindex
extern char *rindex();
#else
#include <time.h>
extern long timezone;
#define search_last strrchr
extern char *strrchr();
#endif
/* Mac time of 00:00:00 GMT, Jan 1, 1970 */
#define TIMEDIFF 0x7c25b080
#define DATABYTES 128
#define BYTEMASK 0xff
#define BYTEBIT 0x100
#define WORDMASK 0xffff
#define WORDBIT 0x10000
#define NAMEBYTES 63
#define H_NLENOFF 1
#define H_NAMEOFF 2
/* 65 <-> 80 is the FInfo structure */
#define H_TYPEOFF 65
#define H_AUTHOFF 69
#define H_FLAGOFF 73
#define H_LOCKOFF 81
#define H_DLENOFF 83
#define H_RLENOFF 87
#define H_CTIMOFF 91
#define H_MTIMOFF 95
#define H_OLD_DLENOFF 81
#define H_OLD_RLENOFF 85
#define F_BUNDLE 0x2000
#define F_LOCKED 0x8000
struct macheader {
char m_name[NAMEBYTES+1];
char m_type[4];
char m_author[4];
short m_flags;
long m_datalen;
long m_rsrclen;
long m_createtime;
long m_modifytime;
} mh;
struct filenames {
char f_info[256];
char f_data[256];
char f_rsrc[256];
} files;
int pre_beta; /* options */
int listmode;
int verbose;
int compressed; /* state variables */
int qformat;
FILE *ifp;
/*
* xbin -- unpack BinHex format file into suitable
* format for downloading with macput
* Dave Johnson, Brown University Computer Science
*
* (c) 1984 Brown University
* may be used but not sold without permission
*
* created ddj 12/16/84
* revised ddj 03/10/85 -- version 4.0 compatibility, other minor mods
* revised ddj 03/11/85 -- strip LOCKED bit from m_flags
* revised ahm 03/12/85 -- System V compatibility
* revised dba 03/16/85 -- (Darin Adler, TMQ Software) 4.0 EOF fixed,
* 4.0 checksum added
* revised ddj 03/17/85 -- extend new features to older formats: -l, stdin
* revised ddj 03/24/85 -- check for filename truncation, allow multiple files
* revised ddj 03/26/85 -- fixed USG botches, many problems w/multiple files
* revised jcb 03/30/85 -- (Jim Budler, amdcad!jimb), revised for compatibility
* with 16-bit int machines
* revised dl 06/16/85 -- (Dan LaLiberte, liberte@uiucdcs) character
* translation speedup
* revised ddj 09/30/85 -- fixed problem with run of RUNCHAR
*/
char usage[] = "usage: \"xbin [-v] [-l] [-o] [-n name] [-] filename\"\n";
main(ac, av)
char **av;
{
char *filename, *macname;
filename = ""; macname = "";
ac--; av++;
while (ac) {
if (av[0][0] == '-') {
switch (av[0][1]) {
case '\0':
filename = "-";
break;
case 'v':
verbose++;
break;
case 'l':
listmode++;
break;
case 'o':
pre_beta++;
break;
case 'n':
if (ac > 1) {
ac--; av++;
macname = av[0];
filename = "";
break;
}
else
goto bad_usage;
default:
goto bad_usage;
}
}
else
filename = av[0];
if (filename[0] != '\0') {
setup_files(filename, macname);
if (listmode) {
print_header();
}
else {
process_forks();
/* now that we know the size of the forks */
forge_info();
}
if (ifp != stdin)
fclose(ifp);
macname = "";
ifp = NULL; /* reset state */
qformat = 0;
compressed = 0;
}
ac--; av++;
}
if (*filename == '\0') {
bad_usage:
fprintf(stderr, usage);
exit(1);
}
}
static char *extensions[] = {
".hqx",
".hcx",
".hex",
"",
NULL
};
setup_files(filename, macname)
char *filename; /* input file name -- extension optional */
char *macname; /* name to use on the mac side of things */
{
char namebuf[256], *np;
char **ep;
int n;
struct stat stbuf;
long curtime;
if (filename[0] == '-') {
ifp = stdin;
filename = "stdin";
}
else {
/* find input file and open it */
for (ep = extensions; *ep != NULL; ep++) {
sprintf(namebuf, "%s%s", filename, *ep);
if (stat(namebuf, &stbuf) == 0)
break;
}
if (*ep == NULL) {
perror(namebuf);
exit(-1);
}
ifp = fopen(namebuf, "rt");
if (ifp == NULL) {
perror(namebuf);
exit(-1);
}
}
if (ifp == stdin) {
curtime = time(0);
mh.m_createtime = curtime;
mh.m_modifytime = curtime;
}
else {
mh.m_createtime = stbuf.st_mtime;
mh.m_modifytime = stbuf.st_mtime;
}
if (listmode || verbose) {
fprintf(stderr, "%s %s%s",
listmode ? "\nListing" : "Converting",
namebuf, listmode ? ":\n" : " ");
}
qformat = find_header(); /* eat mailer header &cetera, intuit format */
if (qformat)
do_q_header(macname);
else
do_o_header(macname, filename);
/* make sure host file name doesn't get truncated beyond recognition */
n = strlen(mh.m_name);
if (n > FNAMELEN - 2)
n = FNAMELEN - 2;
strncpy(namebuf, mh.m_name, n);
namebuf[n] = '\0';
/* get rid of troublesome characters */
for (np = namebuf; *np; np++)
if (*np == ' ' || *np == '/')
*np = '_';
sprintf(files.f_data, "%s.data", namebuf);
sprintf(files.f_rsrc, "%s.rsrc", namebuf);
sprintf(files.f_info, "%s.info", namebuf);
if (verbose)
fprintf(stderr, "==> %s.{info,data,rsrc}\n", namebuf);
}
/* print out header information in human-readable format */
print_header()
{
char *ctime();
printf("macname: %s\n", mh.m_name);
printf("filetype: %.4s, ", mh.m_type);
printf("author: %.4s, ", mh.m_author);
printf("flags: 0x%x\n", mh.m_flags);
if (qformat) {
printf("data length: %ld, ", mh.m_datalen);
printf("rsrc length: %ld\n", mh.m_rsrclen);
}
if (!pre_beta) {
printf("create time: %s", ctime(&mh.m_createtime));
}
}
process_forks()
{
if (qformat) {
/* read data and resource forks of .hqx file */
do_q_fork(files.f_data, mh.m_datalen);
do_q_fork(files.f_rsrc, mh.m_rsrclen);
}
else
do_o_forks();
}
/* write out .info file from information in the mh structure */
forge_info()
{
static char buf[DATABYTES];
char *np;
FILE *fp;
int n;
long tdiff;
struct tm *tp;
#ifdef BSD
struct timeb tbuf;
#else
long bs;
#endif
for (np = mh.m_name; *np; np++)
if (*np == '_') *np = ' ';
buf[H_NLENOFF] = n = np - mh.m_name;
strncpy(buf + H_NAMEOFF, mh.m_name, n);
strncpy(buf + H_TYPEOFF, mh.m_type, 4);
strncpy(buf + H_AUTHOFF, mh.m_author, 4);
put2(buf + H_FLAGOFF, mh.m_flags & ~F_LOCKED);
if (pre_beta) {
put4(buf + H_OLD_DLENOFF, mh.m_datalen);
put4(buf + H_OLD_RLENOFF, mh.m_rsrclen);
}
else {
put4(buf + H_DLENOFF, mh.m_datalen);
put4(buf + H_RLENOFF, mh.m_rsrclen);
/* convert unix file time to mac time format */
#ifdef BSD
ftime(&tbuf);
tp = localtime(&tbuf.time);
tdiff = TIMEDIFF - tbuf.timezone * 60;
if (tp->tm_isdst)
tdiff += 60 * 60;
#else
/* I hope this is right! -andy */
time(&bs);
tp = localtime(&bs);
tdiff = TIMEDIFF - timezone;
if (tp->tm_isdst)
tdiff += 60 * 60;
#endif
put4(buf + H_CTIMOFF, mh.m_createtime + tdiff);
put4(buf + H_MTIMOFF, mh.m_modifytime + tdiff);
}
fp = fopen(files.f_info, "wb");
if (fp == NULL) {
perror("info file");
exit(-1);
}
fwrite(buf, 1, DATABYTES, fp);
fclose(fp);
}
/* eat characters until header detected, return which format */
find_header()
{
int c, at_bol;
char ibuf[BUFSIZ];
/* look for "(This file ...)" line */
while (fgets(ibuf, BUFSIZ, ifp) != NULL) {
if (strncmp(ibuf, "(This file", 10) == 0)
break;
}
at_bol = 1;
while ((c = getc(ifp)) != EOF) {
switch (c) {
case '\n':
case '\r':
at_bol = 1;
break;
case ':':
if (at_bol) /* q format */
return 1;
break;
case '#':
if (at_bol) { /* old format */
ungetc(c, ifp);
return 0;
}
break;
default:
at_bol = 0;
break;
}
}
fprintf(stderr, "unexpected EOF\n");
exit(2);
/* NOTRE